﻿using System;
using System.Threading;
using Windows7.Location;
using Windows7.Sensors;

namespace LaptopLoJack
{
    /// <summary>
    /// Helper class for obtain geographic information
    /// </summary>
    public class GeoHlpr
    {
        /// <summary>
        /// Helper class which encapsulates latitude and longitude in a single
        /// object
        /// </summary>
        public class LljLocation
        {
            public double latitude;
            public double longitude;
        }

        /// <summary>
        /// Delegate type for notifying a caller of location information
        /// </summary>
        /// <param name="loc"></param>
        public delegate void GeoLocationCallbackDelegate(LljLocation loc);

        /// <summary>
        /// Internal thread procedure for retrieving GPS sensor data 
        /// asynchronously
        /// </summary>
        /// <param name="obj"></param>
        static private void _GetLatLong(object obj)
        {
            bool triedOnce = false;

            GeoLocationCallbackDelegate callback = 
                (GeoLocationCallbackDelegate)obj;
            LljLocation loc = new LljLocation();
            LatLongLocationProvider llProv = new LatLongLocationProvider(1000);
            LocationReport report = null;

            while (true)
            {
                try
                {
                    report = llProv.GetReport();
                    break;
                }
                catch (System.Runtime.InteropServices.COMException ce)
                {
                    if (false == triedOnce)
                    {
                        Thread.CurrentThread.Join(2000);
                        triedOnce = true;
                    }
                    else
                    {
                        throw ce;
                    }
                }
            }

            loc.latitude = (double)report.GetValue(
                SensorPropertyKeys.SENSOR_DATA_TYPE_LATITUDE_DEGREES);
            loc.longitude = (double)report.GetValue(
                SensorPropertyKeys.SENSOR_DATA_TYPE_LONGITUDE_DEGREES);

            callback(loc);
        }

        /// <summary>
        /// Prompt the user for permission to obtain sensor data
        /// </summary>
        /// <param name="hwnd"></param>
        static public void RequestUserPermissionForSensorData(
            IntPtr hwnd)
        {
            Guid[] reportGuids = { 
                typeof(Windows7.Location.LatLongLocationReport).GUID 
            };

            LocationProvider.RequestPermissions(hwnd, true, reportGuids);
        }

        /// <summary>
        /// Obtain GPS sensor data asynchronously
        /// </summary>
        /// <param name="callback"></param>
        static public void GetCurrentGeoLocation(
            GeoLocationCallbackDelegate callback)
        {
            Thread t = new Thread(_GetLatLong);
            t.Start(callback);
        }
    }
}
